#include<iostream>
#include<typeinfo>
#include<assert.h>
#include<string>
#include<unistd.h>
#include<any>

class Any
{
    private:

        class holder
        {
            public:
                virtual ~holder() {}
                virtual const std::type_info& type() = 0;
                virtual holder* clone() = 0;
        };

        template<class T>
        class placeholeder :public holder
        {
            public:
                placeholeder(const T& val):
                _val(val){}

                virtual const std::type_info& type() //获取保存的数据类型
                {
                    return typeid(T);
                }
                virtual holder* clone()//针对当前的对象自身 克隆出一个新的子类对象
                {
                    return new placeholeder(_val);
                }

            public:
                T _val;
        };

        holder* _content;
    
    public:
        Any():_content(nullptr){}
        template<class T>
        Any(const T &val):_content(new placeholeder<T>(val)){}
        Any(const Any &other):_content(other._content ? other._content->clone() : nullptr){}

        ~Any(){delete _content;}

        Any &swap(Any& other)
        {
            std::swap(_content,other._content);
            return *this;
        }

        template<class T>
        T* get()//返回子类对象保存的数据的指针
        {
            assert(typeid(T)==_content->type());
            return  &((placeholeder<T>*)_content)->_val;
        }

        template<class T>
        Any& operator=(const T& val)
        {
            Any(val).swap(*this);
            return *this;
        }
        Any& operator=(const Any& other)
        {
            Any(other).swap(*this);
            return *this;
        }
};

class Test
{
    public:
        Test(){std::cout<<"构造"<<std::endl;}
        Test(const Test& t){std::cout<<"拷贝"<<std::endl;}
        ~Test(){std::cout<<"析构"<<std::endl;}
};


int main()
{
    std::any a;
    a = 10;
    int *pi = std::any_cast<int>(&a);

    std::cout<<*pi<<std::endl;

    a = std::string("iloveghx");
    std::string* ps = std::any_cast<std::string>(&a);
    std::cout<<*ps<<std::endl;

    // {
    //     Any a;
    //     Test t;
    //     a = t;
    // }

    // // a = 10;
    // // int *pa = a.get<int>();
    // // std::cout << *pa << std::endl;

    // // a = std::string("sbh&ghx");
    // // std::string *ps = a.get<std::string>();
    // //  std::cout << *ps << std::endl;


    // while(1)sleep(1);
    return 0;
}